`timescale 1ns/1ps

module tb_multi_lia_top_test;

parameter int acc_rate = 10;                       //-------------------------------
parameter int datin_width = 8;
parameter int daout_width = 16;
parameter int mux_num = 1536;
parameter int work_clk_freq = 100_000_000;
localparam int ADDR_WIDTH = $clog2(mux_num);

// DUT inputs
logic sys_clk;
logic rst_n;

logic datin_bram_w_en;
logic [ADDR_WIDTH-1:0] datin_bram_w_addr;
logic [datin_width-1:0] datin_bram_w_data;
logic datin_bram_w_we;
logic pcl7152_busy;

// DUT outputs
wire ttl_signal;

// 实例化 DUT
multi_lia_top_test #(
    .datin_width(datin_width),
    .daout_width(daout_width),
    .mux_num(mux_num),
    .work_clk_freq(work_clk_freq)
) dut (
    .sys_clk(sys_clk),
    .rst_n(rst_n),

    .datin_bram_w_en(datin_bram_w_en),
    .datin_bram_w_addr(datin_bram_w_addr),
    .datin_bram_w_data(datin_bram_w_data),
    .datin_bram_w_we(datin_bram_w_we),
    .pcl7152_busy(pcl7152_busy),

    .ttl_signal(ttl_signal)
);

// sys_clk = 50 MHz
initial sys_clk = 0;
always #1 sys_clk = ~sys_clk; // 20 ns 周期                       //-------------------------------

// 500 Hz 方波信号 sq（周期 2 ms，半周期 1 ms）
logic sq;
initial begin
    sq = 0;
    forever #1_000_00 sq = ~sq;                        //-------------------------------
end

// 初始化与复位
initial begin
    datin_bram_w_en   = 0;
    datin_bram_w_addr = '0;
    datin_bram_w_data = '0;
    datin_bram_w_we   = 0;
    pcl7152_busy      = 0;
    rst_n             = 0;
    #20;                       //-------------------------------
    rst_n             = 1;
end

// 全局写入计数器，用于安全控制 pcl7152_busy
integer active_writers = 0;

// 写入任务：每个触发启动一次并发写入
task automatic write_bram_task(input logic [datin_width-1:0] value);
    integer i;
    begin
        active_writers++;
        pcl7152_busy = (active_writers > 0);

        $display("[%0t] write_bram_task START value=%0h (writers=%0d)", $time, value, active_writers);

        datin_bram_w_en = 1;
        datin_bram_w_we = 1;

        for (i = 0; i < mux_num; i = i + 1) begin
            @(posedge sys_clk);
            datin_bram_w_addr <= i[ADDR_WIDTH-1:0];
            datin_bram_w_data <= value;
        end

        @(posedge sys_clk);
        datin_bram_w_we  = 0;
        datin_bram_w_en  = 0;

        active_writers--;
        pcl7152_busy = (active_writers > 0);

        $display("[%0t] write_bram_task END (writers=%0d)", $time, active_writers);
    end
endtask

// 定时触发线程（严格 500 µs 周期）
initial begin
    wait (rst_n == 1);
    #100;                       //-------------------------------

    fork
        // 定时采样触发器
        begin
            forever begin
                #500_00; // 500 µs                       //-------------------------------
                @(posedge sys_clk);
                fork
                    begin
                        if (sq)
                            write_bram_task(8'd1);
                        else
                            write_bram_task({datin_width{1'b0}});
                    end
                join_none
            end
        end

        // 仿真超时结束
        begin
            #50_000_00; // 仿真 50 ms                       //-------------------------------
            $display("[%0t] SIMULATION FINISH TIMEOUT", $time);
            disable fork;
        end
    join
    $finish;
end

// 波形 dump
initial begin
    $dumpfile("tb_multi_lia_top_test.vcd");
    $dumpvars(0, tb_multi_lia_top_test);
end

endmodule
